package cn.stylefeng.guns.sys.modular.system.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.base.pojo.node.MenuNode;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.base.shiro.ShiroUser;
import cn.stylefeng.guns.sys.core.constant.Const;
import cn.stylefeng.guns.sys.core.constant.factory.ConstantFactory;
import cn.stylefeng.guns.sys.core.constant.state.ManagerStatus;
import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
import cn.stylefeng.guns.sys.core.shiro.ShiroKit;
import cn.stylefeng.guns.sys.core.shiro.service.UserAuthService;
import cn.stylefeng.guns.sys.modular.system.entity.Dept;
import cn.stylefeng.guns.sys.modular.system.entity.Menu;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.factory.UserFactory;
import cn.stylefeng.guns.sys.modular.system.mapper.UserMapper;
import cn.stylefeng.guns.sys.modular.system.model.UserDto;
import cn.stylefeng.roses.core.datascope.DataScope;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 管理员表 服务实现类
 * </p>
 *
 * @author stylefeng
 * @since 2018-12-07
 */
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserAuthService userAuthService;

    @Autowired
    private DeptService deptService;

    
	/**
	 * 获取当前用户的 交付ID
	 * @return deliverId
	 */
	public Long getDeliverId() {

	  ShiroUser currentUser = ShiroKit.getUser();
	  User userthe = new User();
	  if(currentUser==null){
          userthe.setDeliverId(null);
          return null;
	  }
	  String account;
	  if (currentUser!=null && currentUser.getAccount()!=null) {
		  account = currentUser.getAccount();
	  } else {
		  ShiroUser user = ShiroKit.getUserNotNull();
		  if (user!=null && user.getAccount()!=null) {
			  account = user.getAccount();
		} else {
			return null;
		}
	  }
	  userthe = this.getByAccount(account);
	  return userthe.getDeliverId();
	}
	
	/**
	 * 获取当前用户的 交付客户名称
	 * @return deliverName
	 */
	public String getdeliverName() {

	  ShiroUser currentUser = ShiroKit.getUser();
	  User userthe = new User();
	  if(currentUser==null){
          userthe.setDeliverId(null);
          return null;
	  }
	  String account;
	  if (currentUser!=null&&currentUser.getAccount()!=null) {
		  account = currentUser.getAccount();
	  } else {
		  ShiroUser user = ShiroKit.getUserNotNull();
		  if (user!=null&&user.getAccount()!=null) {
			  account = user.getAccount();
		} else {
			return null;
		}
	  }
	  userthe = this.getByAccount(account);
	  return userthe.getDeliverName();
	}
	
	/**
	 * 获取当前用户的 部门ID
	 * @return deptId
	 */
	public Long getDeptId() {
	  ShiroUser currentUser = ShiroKit.getUser();

        User userthe = new User();
        if(currentUser==null){

            return null;
        }


	  Long deptId;
	  if (currentUser!=null&&currentUser.getDeptId()!=null) {
		  deptId = currentUser.getDeptId();
	  } else {
		  ShiroUser user = ShiroKit.getUserNotNull();
		  if (user!=null&&user.getDeptId()!=null) {
			  deptId = user.getDeptId();
		} else {
			return null;
		}
	  }
	  return deptId;
	}

	/**
	*@Description: 获取当前用户ID
	*@Author: WZ
	*@Date: 2019/11/19 15:25
	*/
    public Long getUserId() {

        ShiroUser currentUser = ShiroKit.getUser();

        User userthe = new User();
        if(currentUser==null){

            return null;
        }
        return currentUser.getId();


    }
	  
	/**
	 * 获取当前用户
	 * @return User
	 */
	public User getcurrentUser() {
	  ShiroUser currentUser = ShiroKit.getUser();
	  String account = null;
	  if (currentUser!=null&&currentUser.getAccount()!=null) {
		  account = currentUser.getAccount();
	  } else {
		  ShiroUser user = ShiroKit.getUserNotNull();
		  if (user!=null&&user.getAccount()!=null) {
			  account = user.getAccount();
		} else {
			return null;
		}
	  }
	  User userthe = this.getByAccount(account);
	  return userthe;
	}

    /**
     * 添加用戶
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:51
     */
    public void addUser(UserDto user) {
    	if(user.getOperateId() == null) {
    		Dept dept = deptService.getById(user.getDeptId());
    		user.setOperateId(dept.getOperateId());
    	}

        // 判断账号是否重复
        User theUser = this.getByAccount(user.getAccount());
        if (theUser != null) {
            throw new ServiceException(BizExceptionEnum.USER_ALREADY_REG);
        }

        // 完善账号信息
        String salt = ShiroKit.getRandomSalt(5);
        String password = ShiroKit.md5(user.getPassword(), salt);

        this.save(UserFactory.createUser(user, password, salt));
    }

    /**
     * 修改用户
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:53
     */
    public void editUser(UserDto user) {
        if(ToolUtil.isNotEmpty(user.getDeptId())){
            Dept dept = deptService.getById(user.getDeptId());
            user.setOperateId(dept.getOperateId());
        }

        User oldUser = this.getById(user.getUserId());
        this.updateById(UserFactory.editUser(user, oldUser));
        
//        if (ShiroKit.hasRole(Const.ADMIN_NAME)) {
//            this.updateById(UserFactory.editUser(user, oldUser));
//        } else {
//            this.assertAuth(user.getUserId());
//            ShiroUser shiroUser = ShiroKit.getUserNotNull();
//            if (shiroUser.getId().equals(user.getUserId())) {
//                this.updateById(UserFactory.editUser(user, oldUser));
//            } else {
//                throw new ServiceException(BizExceptionEnum.NO_PERMITION);
//            }
//        }
    }

    /**
     * 删除用户
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:54
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long userId) {

        //不能删除超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new ServiceException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }
        this.assertAuth(userId);
        this.setStatus(userId, ManagerStatus.DELETED.getCode());

        //删除对应的oauth2绑定表
        SqlRunner.db().delete("delete from oauth_user_info where user_id = {0}", userId);
    }

    /**
     * 修改用户状态
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:45
     */
    public int setStatus(Long userId, String status) {
        return this.baseMapper.setStatus(userId, status);
    }

    /**
     * 修改密码
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:45
     */
    public void changePwd(String oldPassword, String newPassword) {
        Long userId = ShiroKit.getUserNotNull().getId();
        User user = this.getById(userId);

        String oldMd5 = ShiroKit.md5(oldPassword, user.getSalt());

        if (user.getPassword().equals(oldMd5)) {
            String newMd5 = ShiroKit.md5(newPassword, user.getSalt());
            user.setLastLoginTime(new Date());
            user.setPassword(newMd5);
            this.updateById(user);
        } else {
            throw new ServiceException(BizExceptionEnum.OLD_PWD_NOT_RIGHT);
        }
    }


    public User getUser() {
        Long userId = ShiroKit.getUserNotNull().getId();
        return this.getById(userId);
    }

    /**
     * 修改最后修改时间
     * @param user
     */
    public void updateLastLoginTimeById(User user){
        User userInfo = this.getById(user.getUserId());
        if(ToolUtil.isNotEmpty(userInfo.getLastLoginTime())){
            this.updateById(user);
        }
    }

    /**
     * 根据条件查询用户列表
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:45
     */
    public Page<Map<String, Object>> selectUsers(DataScope dataScope, String name, String beginTime, String endTime, Long deptId,Long DeliverId,Long deptIdB) {
        Page page = LayuiPageFactory.defaultPage();
        return this.baseMapper.selectUsers(page, dataScope, name, beginTime, endTime, deptId,DeliverId,deptIdB);
    }

    /**
     * 设置用户的角色
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:45
     */
    public int setRoles(Long userId, String roleIds) {
        return this.baseMapper.setRoles(userId, roleIds);
    }

    /**
     * 通过账号获取用户
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:46
     */
    public User getByAccount(String account) {
        return this.baseMapper.getByAccount(account);
    }

    /**
     * 获取用户菜单列表
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:46
     */
    public List<MenuNode> getUserMenuNodes(List<Long> roleList) {
        if (roleList == null || roleList.size() == 0) {
            return new ArrayList<>();
        } else {
            List<MenuNode> menus = menuService.getMenusByRoleIds(roleList);
            return MenuNode.buildTitle(menus);
        }

    }

    /**
     * 获取用户菜单APP列表
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:46
     */
    public List<Menu> getAppRoleMenulist(List<Long> roleList) {
        if (roleList == null || roleList.size() == 0) {
            return new ArrayList<>();
        } else {
            List<Menu> menus = menuService.getAppRoleMenulist(roleList);
            return menus;
        }

    }

	public List<Menu> getAppletsRoleMenulist(List<Long> roleList) {
        if (roleList == null || roleList.size() == 0) {
            return new ArrayList<>();
        } else {
            List<Menu> menus = menuService.getAppletsRoleMenulist(roleList);
            return menus;
        }
	}



    /**
     * 判断当前登录的用户是否有操作这个用户的权限
     *
     * @author fengshuonan
     * @Date 2018/12/24 22:44
     */
    public void assertAuth(Long userId) {
        if (ShiroKit.isAdmin()) {
            return;
        }
        List<Long> deptDataScope = ShiroKit.getDeptDataScope();
        User user = this.getById(userId);
        Long deptId = user.getDeptId();
        if (deptDataScope.contains(deptId)) {
            return;
        } else {
            throw new ServiceException(BizExceptionEnum.NO_PERMITION);
        }

    }

    /**
     * 刷新当前登录用户的信息
     *
     * @author fengshuonan
     * @Date 2019/1/19 5:59 PM
     */
    public void refreshCurrentUser() {
        ShiroUser user = ShiroKit.getUserNotNull();
        Long id = user.getId();
        User currentUser = this.getById(id);
        ShiroUser shiroUser = userAuthService.shiroUser(currentUser);
        ShiroUser lastUser = ShiroKit.getUser();
        BeanUtil.copyProperties(shiroUser, lastUser);
    }

    /**
     * 获取用户的基本信息
     *
     * @author fengshuonan
     * @Date 2019-05-04 17:12
     */
    public Map<String, Object> getUserInfo(Long userId) {
        User user = this.getById(userId);
        Map<String, Object> map = UserFactory.removeUnSafeFields(user);

        HashMap<Object, Object> hashMap = CollectionUtil.newHashMap();
        hashMap.putAll(map);
        map.put("deptName", ConstantFactory.me().getDeptName(user.getDeptId()));
        hashMap.put("roleName", ConstantFactory.me().getRoleName(user.getRoleId()));
        hashMap.put("deptName", ConstantFactory.me().getDeptName(user.getDeptId()));

        return map;
    }

	public List<UserDto> findListBySpec(UserDto userDto,Long operateId) {
		return this.baseMapper.findListBySpec(userDto,operateId);
	}
	
    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    public LayuiPageInfo findPageBySpec(User User,String condition){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, User,condition);
        return LayuiPageFactory.createPageInfo(page);
    }

	public User findByName(User user) {
		return this.baseMapper.findByName(user);
	}

	public List<Menu> getAppletsPermissionlist(List<Long> roleList, String url) {
        if (roleList == null || roleList.size() == 0) {
            return new ArrayList<>();
        } else {
            List<Menu> menus = menuService.getAppletsPermissionlist(roleList,url);
            return menus;
        }
	}
    
}
